/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 **************************************************************************
 * MIFSS  - content storage system
 * 
 *
 * @uthors: uros.kristan@gmail.com (Uroš Kristan ) Urosk.NET
 *         jernej.svigelj@gmail.com (Jernej Švigelj) 
 */
package net.monare.mifss.workers;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import java.util.UUID;

import net.monare.mifss.exceptions.FileHandlerException;
import net.monare.mifss.workers.interfaces.FileHandler;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.tika.Tika;
import org.apache.tika.exception.TikaException;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.parser.AutoDetectParser;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.parser.Parser;
import org.apache.tika.sax.BodyContentHandler;
import org.springframework.stereotype.Component;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;

@Component
public class FileHandlerImpl implements FileHandler {

	private static Logger logger = Logger.getLogger(FileHandlerImpl.class);

	Tika tika;

	public FileHandlerImpl() {
		tika = new Tika();
	}

	@Override
	public String getContentMetaData(File file) {

		StringBuffer sbMetaData = new StringBuffer();

		Metadata metadata = new Metadata();
		ContentHandler handler = new BodyContentHandler(10 * 1024 * 1024);
		Parser parser = new AutoDetectParser();
		ParseContext context = new ParseContext();

		try {
			parser.parse(new FileInputStream(file), handler, metadata, context);
			for (String name : metadata.names()) {
				sbMetaData.append("" + name + " - " + metadata.get(name));
				sbMetaData.append("\n");
			}

			return sbMetaData.toString();

		} catch (FileNotFoundException e) {
			logger.error(e);
		} catch (IOException e) {
			logger.error(e);
		} catch (SAXException e) {
			logger.error(e);
		} catch (TikaException e) {
			logger.error(e);
		}

		return null;

	}

	@Override
	public Date getCurrentDate() {

		return new Date();
	}

	@Override
	public String getFileExtension(String name) {
		String ext = FilenameUtils.getExtension(name);
		return ext;
	}

	@Override
	public String getHashForFile(File file) throws FileHandlerException{
		try {

			logger.debug("starting hash for file");
			String hash = DigestUtils.sha256Hex(new FileInputStream(file));
			logger.debug("stoped hash for file");
			return hash;
			
		} catch (IOException e) {
			
			String errMessage = "Error occured while trying to calculate hash foor " + file.getPath() + " . " + e.getMessage();
			logger.error(errMessage, e);
			throw new FileHandlerException(errMessage, e);
			
		}
		
	}

	@Override
	public String getHashMethod() {

		// TODO reconsider tag
		return "sha256";
	}

	@Override
	public String getMimeType(File file) {

		Path path = Paths.get(file.getPath());
		try {
			String mt = Files.probeContentType(path);
			logger.debug("probe content " + mt);
			if (!StringUtils.isEmpty(mt))
				return mt;
		} catch (IOException e1) {
			logger.error(e1);
		}

		String mime = null;

		try {
			mime = tika.detect(file);
		} catch (IOException e) {
			logger.error(e);
		}

		return mime;
	}

	@Override
	public synchronized String getUniqueId() {

		return UUID.randomUUID().toString();
	}

	@Override
	public String replaceFileExtension(String fileName, String newExtension) {
		if (newExtension.startsWith("."))
			newExtension = newExtension.replaceFirst(".", "");

		String tmp = getFileExtension(fileName);
		tmp = StringUtils.replace(fileName, tmp, newExtension);
		return tmp;
	}

	@Override
	public long getFilesize(File file) {
		if (file != null)
			return file.length();
		return -1;
	}
}
